package cn.stylefeng.guns.modular.transport.controller;

import cn.stylefeng.guns.modular.basic.entity.BasicAddress;
import cn.stylefeng.guns.modular.basic.mapper.BasicAddressMapper;
import cn.stylefeng.guns.modular.basic.model.result.BasicAddressResult;
import cn.stylefeng.guns.modular.basic.service.BasicAddressService;
import cn.stylefeng.guns.modular.basic.service.BasicOperateService;
import cn.stylefeng.guns.modular.transport.entity.*;
import cn.stylefeng.guns.modular.transport.mapper.TDispatchMapper;
import cn.stylefeng.guns.modular.transport.model.result.MapRouteResult;
import cn.stylefeng.guns.modular.transport.model.result.MapTerminalResult;
import cn.stylefeng.guns.modular.transport.model.result.MapTrackResult;
import cn.stylefeng.guns.modular.transport.model.result.TDispatchResult;
import cn.stylefeng.guns.modular.transport.service.MapDisptchService;
import cn.stylefeng.guns.modular.transport.service.TDispatchService;
import cn.stylefeng.guns.modular.transport.service.TraceService;
import cn.stylefeng.guns.modular.transport.utils.MapTrackUtils;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author : like
 * @date : 2024/8/9 18:05
 * @Version: 1.0
 */
@Slf4j
@Api(tags = "高德猎鹰")
@Controller
@RequestMapping("/MapTransport")
public class MapTransportController {

    private String PREFIX = "/transport/tMap";

    @Autowired
    private TraceService traceService;

    @Autowired
    private MapTrackUtils mapTrackUtils;

    @Autowired
    private BasicOperateService basicOperateService;
    @Autowired
    private MapDisptchService mapDisptchService;

    @Autowired
    private MongoTemplate mongoTemplate;;

    @RequestMapping("/monitor")
    public String monitor(Model model) {
        List<Trace> list = traceService.list(new QueryWrapper<Trace>().groupBy("operate_id"));
        model.addAttribute("basicOperatelist", list);
        return PREFIX + "/tMonitor.html";
    }

    @RequestMapping("/realTime")
    public String realTime(Model model) {
        List<Trace> list = traceService.list(new QueryWrapper<Trace>().groupBy("operate_id"));
        model.addAttribute("basicOperatelist", list);
        return PREFIX + "/tRealTime.html";
    }


    // 轨迹监控 / 查询轨迹信息
    @ApiOperation(value = "查询轨迹信息Web", notes = "根据服务编号、终端编号、轨迹编号等查询轨迹信息Web")
    @ResponseBody
    @RequestMapping(value = "/queryTrackWeb", method = {RequestMethod.GET})
    public List<MapRouteResult> queryTrackWeb(
            @RequestParam(required = false) String sid,
            @RequestParam(required = false) String tid,
            @RequestParam(required = false) String trid,
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            @RequestParam(required = false, defaultValue = "denoise=1,mapmatch=1,attribute=1,threshold=0,mode=driving") String correction,
            @RequestParam(required = false, defaultValue = "1") Integer recoup,
            @RequestParam(required = false, defaultValue = "50") Integer gap,
            @RequestParam(required = false, defaultValue = "1") Integer ispoints,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false, defaultValue = "999") Integer pagesize,
            @RequestParam(required = false) String dispatchNumber,
            @RequestParam(required = false) String operateId
    ) {
        boolean all = dispatchNumber == null && operateId == null;
        QueryWrapper<Trace> traceQueryWrapper = new QueryWrapper<>();

        // 设置日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startOfPreviousDay = LocalDate.now().minusDays(1).atStartOfDay();
        LocalDateTime endOfDay = LocalDate.now().plusDays(1).atStartOfDay().minusSeconds(1);

        String startOfDayStr = startOfPreviousDay.format(formatter);
        String endOfDayStr = endOfDay.format(formatter);

        if (all) {
            // 当前默认查询当天和前一天 稳定后添加 .isNotNull("end_time")
            traceQueryWrapper
                    .ge("created_at", startOfDayStr)
                    .lt("created_at", endOfDayStr)
                    .last("LIMIT 10");
        } else {
            if (!operateId.isEmpty()) {
                traceQueryWrapper.eq("operate_id", operateId);
            }
            traceQueryWrapper
                    .like("trace_name", dispatchNumber)
                    .ge("created_at", startOfDayStr)
                    .lt("created_at", endOfDayStr);
        }

        // 1、根据遍历轨迹信息
        List<MapRouteResult> routesList = new ArrayList<>();
        int currentPage = page != null ? page : 1;

        // 2、控制分页查询，直到没有更多数据
        List<Trace> list = traceService.list(traceQueryWrapper);
        for (Trace trace : list) {
            boolean hasMoreData = true;

            while (hasMoreData) {
                String result = mapTrackUtils.queryTrackInfo(trace.getServiceId(), trace.getTerminalId(), trace.getTraceId(), startTime, endTime, correction, recoup, gap, ispoints, currentPage, pagesize);
                JSONObject jsonObject = new JSONObject(result);

                try {
                    JSONObject dataObject = jsonObject.getJSONObject("data");
                    JSONArray tracksArray = dataObject.getJSONArray("tracks");
                    JSONObject firstTrack = tracksArray.getJSONObject(0);
                    int pointsCount = firstTrack.getInt("counts");

                    // 3、遍历轨迹数据
                    for (int i = 0; i < tracksArray.length(); i++) {
                        JSONObject track = tracksArray.getJSONObject(i);
                        String trname = track.getString("trname");

                        MapRouteResult route = routesList.stream()
                                .filter(r -> r.getName().equals(trname))
                                .findFirst()
                                .orElseGet(() -> {
                                    MapRouteResult newRoute = new MapRouteResult();
                                    newRoute.setName(trname);
                                    newRoute.setPath(new ArrayList<>());
//                                    routesList.add(newRoute);
                                    return newRoute;
                                });

                        JSONArray pointsArray = track.getJSONArray("points");
                        for (int j = 0; j < pointsArray.length(); j++) {
                            JSONObject point = pointsArray.getJSONObject(j);
                            String location = point.getString("location");
                            String[] coords = location.split(",");
                            List<Double> coordList = Arrays.asList(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]));
                            route.getPath().add(coordList);
                        }

                        if (currentPage == 1 && route.getPath().size() > 10) {
                            routesList.add(route);
                            log.info("------历史轨迹信息------" , route);
                        }
//                        System.out.println("-----------+++" + route);
                    }

                    if (pointsCount > pagesize){
                        int count = currentPage * pagesize;
                        // 检查是否需要继续查询下一页
                        if (pointsCount < count) {
                            hasMoreData = false;
                        }
                    }else {
                        hasMoreData = false;
                    }

                    currentPage++;

                } catch (Exception e) {
                    e.printStackTrace();
                    hasMoreData = false;
                }
            }
            currentPage = 1;
        }
        return routesList;
    }



//    //TODO 轨迹监控 / 查询轨迹信息
//    // 轨迹监控 / 查询轨迹信息
//    @ApiOperation(value = "查询轨迹信息Web", notes = "根据服务编号、终端编号、轨迹编号等查询轨迹信息Web")
//    @ResponseBody
//    @RequestMapping(value = "/queryTrackWebNew", method = {RequestMethod.GET})
//    public List<MapRouteResult> queryTrackWebNew(
//            @RequestParam(required = false) String sid,
//            @RequestParam(required = false) String tid,
//            @RequestParam(required = false) String trid,
//            @RequestParam(required = false) String startTime,
//            @RequestParam(required = false) String endTime,
//            @RequestParam(required = false, defaultValue = "denoise=1,mapmatch=1,attribute=1,threshold=0,mode=driving") String correction,
//            @RequestParam(required = false, defaultValue = "1") Integer recoup,
//            @RequestParam(required = false, defaultValue = "50") Integer gap,
//            @RequestParam(required = false, defaultValue = "1") Integer ispoints,
//            @RequestParam(required = false) Integer page,
//            @RequestParam(required = false, defaultValue = "999") Integer pagesize,
//            @RequestParam(required = false) String dispatchNumber,
//            @RequestParam(required = false) String operateId
//    ) {
//        List<MapRouteResult> routesList = new ArrayList<>();
//
//
//        List<MapDisptchNew> byId = mapDisptchService.getMapDisptch(dispatchNumber,operateId);
//        byId.forEach(mapDisptch -> {
//            List<List<Double>> paths = new   ArrayList<>();
//            cn.hutool.json.JSONArray points = new cn.hutool.json.JSONArray(mapDisptch.getPoints());
//            points.stream().forEach(point -> {
//                String[] coord = ((cn.hutool.json.JSONObject)point).get("location").toString().split(",");
//                List<Double> path = new ArrayList<>();
//                path.add(Double.parseDouble(coord[0]));
//                path.add(Double.parseDouble(coord[1]));
//                paths.add(path);
//            });
//            MapRouteResult mapRouteResult = new MapRouteResult();
//            mapRouteResult.setName(mapDisptch.getCarnumber() + "-" + mapDisptch.getDispatchNumber());
//            mapRouteResult.setPath(paths);
//            routesList.add(mapRouteResult);
//        });
//        return routesList;
//    }


    //TODO 轨迹监控 / 查询轨迹信息
    // 轨迹监控 / 查询轨迹信息
    @ApiOperation(value = "查询轨迹信息Web", notes = "根据服务编号、终端编号、轨迹编号等查询轨迹信息Web")
    @ResponseBody
    @RequestMapping(value = "/queryTrackWebNew", method = {RequestMethod.GET})
    public List<MapRouteResult> queryTrackWebNew(
            @RequestParam(required = false) String sid,
            @RequestParam(required = false) String tid,
            @RequestParam(required = false) String trid,
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            @RequestParam(required = false, defaultValue = "denoise=1,mapmatch=1,attribute=1,threshold=0,mode=driving") String correction,
            @RequestParam(required = false, defaultValue = "1") Integer recoup,
            @RequestParam(required = false, defaultValue = "50") Integer gap,
            @RequestParam(required = false, defaultValue = "1") Integer ispoints,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false, defaultValue = "999") Integer pagesize,
            @RequestParam(required = false) String dispatchNumber,
            @RequestParam(required = false) String operateId
    ) {
        List<MapRouteResult> routesList = new ArrayList<>();

        List<MapDisptchMongo> byId = mapDisptchService.getMapDisptchMongo(dispatchNumber,operateId);
        byId.forEach(mapDisptch -> {
            MapDisptchMongo mapDisptchMongo = mongoTemplate.findById(mapDisptch.getDispatchNumber(), MapDisptchMongo.class);

            if (mapDisptchMongo != null ){
                List<MapPoints> points = mapDisptchMongo.getPoints();

                List<List<Double>> paths = new   ArrayList<>();
                points.stream().forEach(point -> {
                    String[] coord = point.getLocation().split(",");
                    List<Double> path = new ArrayList<>();
                    path.add(Double.parseDouble(coord[0]));
                    path.add(Double.parseDouble(coord[1]));
                    paths.add(path);
                });
                MapRouteResult mapRouteResult = new MapRouteResult();
                mapRouteResult.setName(mapDisptch.getCarnumber() + "-" + mapDisptch.getDispatchNumber());
                mapRouteResult.setPath(paths);
                routesList.add(mapRouteResult);
            }else {
                log.info("-------没有轨迹数据-------{}" , mapDisptch.getDispatchNumber());
            }

        });
        return routesList;
    }

    @ApiOperation(value = "查询终端实时位置Web", notes = "根据服务id和终端id，轨迹id查询终端实时位置Web")
    @ResponseBody
    @RequestMapping(value = "/queryTerminalLocationWeb", method = {RequestMethod.GET})
    public List<MapTerminalResult> queryTerminalLocationWeb(
            @RequestParam(required = false)  String sid,
            @RequestParam(required = false)  String tid,
            @RequestParam(required = false) String trid,
            @RequestParam(required = false, defaultValue = "false") boolean correction,
            @RequestParam(required = false) String operateId
    ) throws IOException {
        boolean all = operateId == null;
        QueryWrapper<Trace> traceQueryWrapper = new QueryWrapper<>();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 当天时间开始，以及当天最后一秒时间
        LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
        LocalDateTime endOfDay = LocalDate.now().plusDays(1).atStartOfDay().minusSeconds(1);
        // 将 LocalDateTime 转换为字符串
        String startOfDayStr = startOfDay.format(formatter);
        String endOfDayStr = endOfDay.format(formatter);

        if (all) {
            // 如果没有指定operateId，则查询所有数据，但限制在当天
            traceQueryWrapper
                    .ge("created_at", startOfDayStr)
                    .lt("created_at", endOfDayStr);
        } else {
            // 如果指定了operateId，则在查询特定部门的数据时，也限制在当天
            traceQueryWrapper
                    .eq("operate_id", operateId)
                    .ge("created_at", startOfDayStr)
                    .lt("created_at", endOfDayStr);
        }

        // 遍历封装
        List<Trace> list = traceService.list(traceQueryWrapper);

        List<MapTerminalResult> results = new ArrayList<>();

        for (Trace trace : list){
            String serviceId = trace.getServiceId();
            String terminalId = trace.getTerminalId();

            String result = mapTrackUtils.queryTerminalLocation(serviceId, terminalId, trid, correction);
            ObjectMapper objectMapper = new ObjectMapper();
            MapTerminalResult mapTerminalResult = objectMapper.readValue(result, MapTerminalResult.class);
            mapTerminalResult.setTerminalName(trace.getTerminalName());
            mapTerminalResult.setTraceName(trace.getTraceName());

            if (mapTerminalResult.getData() != null && mapTerminalResult.getData().getLocation() != null){
                results.add(mapTerminalResult);
            }
        }
        log.info("-----------实时定位----------",results);
//        System.out.println("----------------results" + results);
        return results;
    }

    //TODO 轨迹监控 / 查询轨迹信息
    @ApiOperation(value = "查询终端实时位置Web", notes = "根据服务id和终端id，轨迹id查询终端实时位置Web")
    @ResponseBody
    @RequestMapping(value = "/queryTerminalLocationWebNew", method = {RequestMethod.GET})
    public List<MapTerminalResult> queryTerminalLocationWebNew(
            @RequestParam(required = false)  String sid,
            @RequestParam(required = false)  String tid,
            @RequestParam(required = false) String trid,
            @RequestParam(required = false, defaultValue = "false") boolean correction,
            @RequestParam(required = false) String operateId
    ) throws IOException {


        List<MapTerminalResult> results = new ArrayList<>();

        List<MapDisptchMongo> byId = mapDisptchService.getMapDisptchMongoOnWay(operateId);

        byId.forEach(mapDisptch -> {
            MapDisptchMongo mapDisptchMongo = mongoTemplate.findById(mapDisptch.getDispatchNumber(), MapDisptchMongo.class);

            if (mapDisptchMongo != null ){
                MapPoints lastPoints = mapDisptchMongo.getLastPoints();
                MapTerminalResult mapTerminalResult = new MapTerminalResult();
                ObjectMapper objectMapper = new ObjectMapper();
                MapTerminalResult.TrackData trackData = null;
                try {
                    JSONObject jsonObject = new JSONObject(lastPoints);
                    trackData = objectMapper.readValue(jsonObject.toString(), MapTerminalResult.TrackData.class);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mapTerminalResult.setData(trackData);
                mapTerminalResult.setTerminalName(mapDisptch.getCarnumber());
                mapTerminalResult.setTraceName(mapDisptch.getCarnumber() + "-" + mapDisptch.getDispatchNumber());
                results.add(mapTerminalResult);
                log.info("-------有轨迹数据-------{}" , mapDisptch.getDispatchNumber());
            }else {
                log.info("-------没有轨迹数据-------{}" , mapDisptch.getDispatchNumber());
            }
        });

        return results;
    }





    /************************************************* 高德猎鹰服务管理 **************************************************/


    // 创建轨迹服务
    @ApiOperation(value = "创建轨迹服务", notes = "根据服务名和描述创建轨迹服务")
    @ResponseBody
    @RequestMapping(value = "/createTrackService",method = {RequestMethod.POST})
    public ResponseData createTrackService(@RequestParam String serviceName,
                                           @RequestParam(required = false) String desc) {
        try {
            String result = mapTrackUtils.createTrackService(serviceName, desc);
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("创建轨迹服务失败：" + e.getMessage());
        }
    }

    // 更新轨迹服务
    @ApiOperation(value = "更新轨迹服务", notes = "根据服务id修改服务名和描述")
    @ResponseBody
    @RequestMapping(value = "/updateTrackService",method = {RequestMethod.POST})
    public ResponseData updateTrackService(@RequestParam String sid,
                                           @RequestParam(required = false) String name,
                                           @RequestParam(required = false) String desc) {
        try {
            String result = mapTrackUtils.updateTrackService(sid, name, desc);
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("更新轨迹服务失败：" + e.getMessage());
        }
    }

    // 查看轨迹服务
    @ApiOperation(value = "查看轨迹服务列表", notes = "根据高德Key查看轨迹服务列表")
    @ResponseBody
    @RequestMapping(value = "/queryTrackServiceList",method = {RequestMethod.GET})
    public ResponseData queryTrackServiceList() {
        try {
            String result = mapTrackUtils.queryTrackServiceList();
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("查看轨迹服务失败：" + e.getMessage());
        }
    }

    // 删除轨迹服务
    @ApiOperation(value = "删除轨迹服务", notes = "根据服务sid删除")
    @ResponseBody
    @RequestMapping(value = "/delTrackService",method = {RequestMethod.POST})
    public ResponseData delTrackService(@RequestParam String sid) {
        try {
            String result = mapTrackUtils.delTrackService(sid);
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("删除轨迹服务失败：" + e.getMessage());
        }
    }

    /*************************************************** 终端管理 ****************************************************/



    // 修改终端
    @ApiOperation(value = "更新终端", notes = "根据服务id和终端id修改终端名称和描述")
    @ResponseBody
    @RequestMapping(value = "/updateTerminal",method = {RequestMethod.POST})
    public ResponseData updateTerminal(@RequestParam String sid,
                                       @RequestParam String tid,
                                       @RequestParam(required = false) String name,
                                       @RequestParam(required = false) String desc) {
        try {
            String result = mapTrackUtils.updateTerminal(sid, tid, name, desc);
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("修改终端失败：" + e.getMessage());
        }
    }

    // 删除终端
    @ApiOperation(value = "删除终端", notes = "根据服务id和终端id删除终端")
    @ResponseBody
    @RequestMapping(value = "/delTerminal",method = {RequestMethod.POST})
    public ResponseData delTerminal(@RequestParam String sid,
                                    @RequestParam String tid) {
        try {
            String result = mapTrackUtils.delTerminal(sid, tid);
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("删除终端失败：" + e.getMessage());
        }
    }



    // 查询终端实时位置
    @ApiOperation(value = "查询终端实时位置", notes = "根据服务id和终端id，轨迹id查询终端实时位置")
    @ResponseBody
    @RequestMapping(value = "/queryTerminalLocation", method = {RequestMethod.GET})
    public MapTerminalResult queryTerminalLocation(@RequestParam String sid,
                                                   @RequestParam String tid,
                                                   @RequestParam(required = false) String trid,
                                                   @RequestParam(required = false, defaultValue = "false") boolean correction) throws IOException {
        String result = mapTrackUtils.queryTerminalLocation(sid, tid, trid, correction);
        ObjectMapper objectMapper = new ObjectMapper();
        MapTerminalResult mapTerminalResult = objectMapper.readValue(result, MapTerminalResult.class);
        return mapTerminalResult;
    }

    /*************************************************** 轨迹管理 ****************************************************/



    // 删除轨迹
    @ApiOperation(value = "删除轨迹", notes = "根据服务id和终端id和轨迹id删除轨迹")
    @ResponseBody
    @RequestMapping(value = "/delTrace",method = {RequestMethod.POST})
    public ResponseData delTrace(@RequestParam String sid,
                                 @RequestParam String tid,
                                 @RequestParam String trid) {
        try {
            String result = mapTrackUtils.delTrace(sid, tid, trid);

            Map<String, Object> delMap = new HashMap<>();
            delMap.put("service_id",sid);
            delMap.put("terminal_id",tid);
            delMap.put("trace_id",trid);
            traceService.removeByMap(delMap);

            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("删除轨迹失败：" + e.getMessage());
        }
    }


    // 查询轨迹信息
    @ApiOperation(value = "查询轨迹信息", notes = "根据服务编号、终端编号、轨迹编号等查询轨迹信息")
    @ResponseBody
    @RequestMapping(value = "/queryTrackInfo", method = {RequestMethod.GET})
    public MapTrackResult queryTrackInfo(
            @RequestParam String sid,
            @RequestParam String tid,
            @RequestParam(required = false) String trid,
            @RequestParam(required = false) String startTime,
            @RequestParam(required = false) String endTime,
            @RequestParam(required = false, defaultValue = "denoise=1,mapmatch=1,attribute=1,threshold=0,mode=driving") String correction,
            @RequestParam(required = false, defaultValue = "1") Integer recoup,
            @RequestParam(required = false, defaultValue = "50") Integer gap,
            @RequestParam(required = false, defaultValue = "1") Integer ispoints,
            @RequestParam(required = false) Integer page,
            @RequestParam(required = false, defaultValue = "999") Integer pagesize) throws IOException {
        String result = mapTrackUtils.queryTrackInfo(
                sid, tid, trid, startTime, endTime, correction, recoup, gap, ispoints, page, pagesize);
        ObjectMapper objectMapper = new ObjectMapper();
        MapTrackResult mapTrackResult = objectMapper.readValue(result, MapTrackResult.class);
        return mapTrackResult;
    }

    // 根据关键字查询终端
    @ApiOperation(value = "根据关键字查询终端", notes = "根据关键字查询终端")
    @ResponseBody
    @RequestMapping(value = "/queryTerminalByKeyword",method = {RequestMethod.GET})
    public ResponseData queryTerminalByKeyword(@RequestParam String sid,
                                               @RequestParam String keywords,
                                               @RequestParam(required = false) String filter,
                                               @RequestParam(required = false) String sortrule,
                                               @RequestParam(required= false) Integer page,
                                               @RequestParam(required= false) Integer pageSize
    ){
        try {
            String result = mapTrackUtils.queryTerminalByKeyword(sid, keywords, filter, sortrule, page, pageSize);
            return ResponseData.success(result);
        } catch (Exception e) {
            return ResponseData.error("查询终端失败：" + e.getMessage());
        }
    }

    /*************************************************** 方法抽取 ****************************************************/

    private String processTrace(Trace trace, List<MapRouteResult> routesList, String startTime, String endTime, String correction,
                              Integer recoup, Integer gap, Integer ispoints, Integer page, Integer pagesize)
            throws JSONException {
        String sid = trace.getServiceId();
        String tid = trace.getTerminalId();
        String trid = trace.getTraceId();
        String result = mapTrackUtils.queryTrackInfo(sid, tid, trid, startTime, endTime, correction, recoup, gap, ispoints, page, pagesize);

        JSONObject jsonObject = new JSONObject(result);

        JSONObject dataObject = jsonObject.getJSONObject("data");
        JSONArray tracksArray = dataObject.getJSONArray("tracks");

        for (int i = 0; i < tracksArray.length(); i++) {
            JSONObject track = tracksArray.getJSONObject(i);

            // 创建一个 MapRouteResult 对象
            MapRouteResult route = new MapRouteResult();
            route.setName(track.getString("trname"));

            JSONArray pointsArray = track.getJSONArray("points");
            List<List<Double>> pathList = new ArrayList<>();

            for (int j = 0; j < pointsArray.length(); j++) {
                JSONObject point = pointsArray.getJSONObject(j);
                String location = point.getString("location");
                String[] coords = location.split(",");
                List<Double> coordList = Arrays.asList(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]));
                pathList.add(coordList);
            }
            route.setPath(pathList);
            routesList.add(route);
        }
        return result;
    }

    /*******************************************************  测试方法 *************************************************/

    @Autowired
    private BasicAddressService basicAddressService;

    @Autowired
    private BasicAddressMapper basicAddressMapper;

    @Autowired
    private TDispatchMapper tDispatchMapper;

    @Autowired
    private TDispatchService tDispatchService;

    @ApiOperation(value = "路径规划", notes = "路径规划")
    @ResponseBody
    @RequestMapping(value = "/getRoute",method = {RequestMethod.GET})
    public void getRoute(){
        // 1.济宁
        /**
         * 39	齐河好想来仓配项目
         * 86	济宁好想来仓配项目
         * 42	沈阳好想来仓配项目
         * 83	长春好想来仓配项目
         *
         * 44	天津好想来仓配项目
         */
        List<TDispatchResult> tDispatchResults = tDispatchMapper.selectByRoutr();
        // 天津起点
        String origin = "117.351155,39.189443";

        // 存储记录 创建txt文件
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:\\Office\\Work\\txt\\TJ.txt", true))) {
            for (TDispatchResult tDispatchResult : tDispatchResults) {
                // 数据格式 聊城周楼小学店+聊城育新路店+聊城恒山路店
                String getUnits = tDispatchResult.getGetUnits();

                String[] units = getUnits.split("\\+");

                List<String> waypointsList = new ArrayList<>();
                // 终点
                String destination = "";

                for (int i = 0; i < units.length; i++) {
                    String longitude = "";
                    String latitude = "";
                    try {
                        // 1.济宁
                        /**
                         * 48	南京万好供应链管理有限公司齐河分公司
                         * 108	南京万好供应链管理有限公司济宁分公司
                         * 53	南京万好供应链管理有限公司沈阳分公司
                         * 104	南京万好供应链管理有限公司长春分公司
                         *
                         * 60	南京万好供应链管理有限公司天津分公司
                         */
                        BasicAddressResult basicAddressResult = basicAddressMapper.selectAddress(units[i]);
                        longitude = basicAddressResult.getLongitude();
                        latitude = basicAddressResult.getLatitude();
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                    // 构建途径点字符串
                    if (i < units.length - 1) {
                        // 不是最后一个点，添加到途径点列表
                        waypointsList.add(longitude + "," + latitude);
                    } else {
                        // 最后一个点，设置为终点
                        destination = longitude + "," + latitude;
                    }
                }

                // 构建途径点字符串
                String waypoints = String.join(";", waypointsList);

                // 打印起点、终点和途径点
                System.out.println("Origin: " + origin);
                System.out.println("Destination: " + destination);
                System.out.println("Waypoints: " + waypoints);

                StringBuilder stringBuilder = new StringBuilder("https://restapi.amap.com/v3/direction/driving");
                stringBuilder.append("?key=c458de37c0d4d7880ef99c0bfdd58c91");
                stringBuilder.append("&origin=").append(origin);
                stringBuilder.append("&destination=").append(destination);
                stringBuilder.append("&waypoints=").append(waypoints);
                stringBuilder.append("&extensions=").append("all");

                try {
                    // 发送GET请求并获取响应
                    String url = stringBuilder.toString();
                    RestTemplate restTemplate = new RestTemplate();
                    String response = restTemplate.getForObject(url, String.class);

                    JSONObject jsonObject = new JSONObject(response);
                    JSONObject route = jsonObject.getJSONObject("route");
                    JSONArray paths = route.getJSONArray("paths");
                    JSONObject path = paths.getJSONObject(0);
                    Double distance = (double) path.getInt("distance");

                    distance = distance / 1000;

                    TDispatch tDispatch = new TDispatch();
                    tDispatch.setId(tDispatchResult.getId());
                    tDispatch.setMileageTraveled(String.valueOf(distance));
//                    tDispatchService.updateById(tDispatch);

                    // 写入文件
                    writer.write("--id:" + tDispatchResult.getId() + " dispatchNumber:" + tDispatchResult.getDispatchNumber() + " 新距离:" + distance + " 原距离:" + tDispatchResult.getMileageTraveled());
                    writer.newLine();
                    writer.flush();  // 确保数据写入

                    System.out.println("--id:" + tDispatchResult.getId() + " dispatchNumber:"+ tDispatchResult.getDispatchNumber() + " 新距离:"+distance + " 原距离"+ tDispatchResult.getMileageTraveled());

                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    @ApiOperation(value = "根据经纬度获取省市区", notes = "根据经纬度获取省市区")
    @ResponseBody
    @RequestMapping(value = "/getGeoWeb",method = {RequestMethod.GET})
    public void getGeoWeb(){
        List<BasicAddressResult> basicAddressResults = basicAddressMapper.selectByGeo();
        for (BasicAddressResult basicAddressResult : basicAddressResults){

            String longitude = basicAddressResult.getLongitude();
            String latitude = basicAddressResult.getLatitude();
            String location = longitude + "," + latitude;
            System.out.println("---------------- "+basicAddressResult.getId());
            StringBuilder stringBuilder = new StringBuilder("https://restapi.amap.com/v3/geocode/regeo");
            stringBuilder.append("?key=c458de37c0d4d7880ef99c0bfdd58c91");
            stringBuilder.append("&location=").append(location);
            stringBuilder.append("&radius=").append(1000);
            stringBuilder.append("&extensions=").append("all");
            try{
                // 发送GET请求并获取响应
                String url = stringBuilder.toString();
                RestTemplate restTemplate = new RestTemplate();
                String response = restTemplate.getForObject(url, String.class);

                // 将字符串转换为JSONObject
                JSONObject jsonObject = new JSONObject(response);
                JSONObject addressComponent = jsonObject.getJSONObject("regeocode").getJSONObject("addressComponent");

                // 提取 province, city, district
                String province = addressComponent.getString("province");
                String city = "";
                try{
                    city = addressComponent.getString("city");
                }catch (Exception e){
                    city = province;
                    e.printStackTrace();
                }
                String district = addressComponent.getString("district");

                // 打印结果
                BasicAddress basicAddress = new BasicAddress();
                basicAddress.setId(basicAddressResult.getId());
                basicAddress.setSheng(province);
                basicAddress.setShi(city);
                basicAddress.setQu(district);
                if (district != null){
                    basicAddressService.updateById(basicAddress);
                    System.out.println("---------------- " + basicAddress);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @ApiOperation(value = "根据经纬度获取省市区", notes = "根据经纬度获取省市区")
    @ResponseBody
    @RequestMapping(value = "/getGeoWebHA", method = {RequestMethod.GET})
    public void getGeoWebHA() {
        List<BasicAddressResult> basicAddressResults = basicAddressMapper.selectByGeo();
        List<BasicAddress> addressesToUpdate = new ArrayList<>();

        for (BasicAddressResult basicAddressResult : basicAddressResults) {
            String longitude = basicAddressResult.getLongitude();
            String latitude = basicAddressResult.getLatitude();
            String location = longitude + "," + latitude;
            System.out.println("---------------- " + basicAddressResult.getId());
            StringBuilder stringBuilder = new StringBuilder("https://restapi.amap.com/v3/geocode/regeo");
            stringBuilder.append("?key=c458de37c0d4d7880ef99c0bfdd58c91");
            stringBuilder.append("&location=").append(location);
            stringBuilder.append("&radius=").append(1000);
            stringBuilder.append("&extensions=").append("all");

            try {
                // 发送GET请求并获取响应
                String url = stringBuilder.toString();
                RestTemplate restTemplate = new RestTemplate();
                String response = restTemplate.getForObject(url, String.class);

                // 将字符串转换为JSONObject
                JSONObject jsonObject = new JSONObject(response);
                JSONObject addressComponent = jsonObject.getJSONObject("regeocode").getJSONObject("addressComponent");

                // 提取 province, city, district
                String province = addressComponent.getString("province");
                String city = "";
                try {
                    city = addressComponent.getString("city");
                } catch (Exception e) {
                    city = province;
                    e.printStackTrace();
                }
                String district = addressComponent.getString("district");

                // 创建 BasicAddress 对象
                BasicAddress basicAddress = new BasicAddress();
                basicAddress.setId(basicAddressResult.getId());
                basicAddress.setSheng(province);
                basicAddress.setShi(city);
                basicAddress.setQu(district);

                if (district != null) {
                    addressesToUpdate.add(basicAddress);
                    System.out.println("---------------- " + basicAddress);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 统一更新数据库
        if (!addressesToUpdate.isEmpty()) {
            basicAddressService.updateBatchById(addressesToUpdate);
        }
    }


    @ApiOperation(value = "更正地理编码", notes = "更正地理编码")
    @ResponseBody
    @RequestMapping(value = "/getGeocodeWeb",method = {RequestMethod.GET})
    public void getGeocodeWeb(){
        List<BasicAddress> list = basicAddressService.list();

        List<BasicAddress> filteredList = list.stream()
                .filter(basicAddress -> {
                    String longitude = basicAddress.getLongitude();
                    // 检查经度长度是否大于10，并且不等于特定的值
                    return longitude == null || longitude.length() > 10;
                })
                .collect(Collectors.toList());

        for (BasicAddress basicAddress : filteredList) {
            String address = basicAddress.getAddress();
            String longitude = basicAddress.getLongitude();
            String latitude = basicAddress.getLatitude();
            System.out.println("原经纬度:" + longitude+","+latitude);
            String result = this.getGeocode(address,null);

            if (Objects.equals(result, "123")){
                continue;
            }else {
                System.out.println("新经纬度" + result);

                String s = result.split(",")[0];
                String s1 = result.split(",")[1];

                System.out.println(s+","+s1);

                BasicAddress basicAddress1 = new BasicAddress();
                basicAddress1.setId(basicAddress.getId());
                basicAddress1.setLongitude(result.split(",")[0]);
                basicAddress1.setLatitude(result.split(",")[1]);
//                basicAddressService.updateById(basicAddress1);
            }
        }
    }


    public String getGeocode(String address, String city) {
        // 使用StringBuilder构建请求URL
        StringBuilder stringBuilder = new StringBuilder("https://restapi.amap.com/v3/geocode/geo");
        stringBuilder.append("?key=7dcc341a969e116364b64dfb6bca1d90");
        stringBuilder.append("&address=").append(address);

        if (city != null && !city.isEmpty()) {
            stringBuilder.append("&city=").append(city);
        }

        String url = stringBuilder.toString();

        // 发送GET请求并获取响应
        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject(url, String.class);

        // 将字符串转换为JSONObject
        JSONObject jsonObject = new JSONObject(response);

        // 获取geocodes数组
        if (!jsonObject.has("geocodes")) {
            return "123";
        }else {
            JSONArray geocodesArray = jsonObject.getJSONArray("geocodes");
            if (geocodesArray.length() > 0) {
                JSONObject geocodeObject = geocodesArray.getJSONObject(0);
                String location = geocodeObject.getString("location");

                // 分割经纬度
                String[] locationParts = location.split(",");
                if (locationParts.length == 2) {
                    double longitude = Double.parseDouble(locationParts[0]);
                    double latitude = Double.parseDouble(locationParts[1]);

                    // 打印经纬度
                    System.out.println("经度: " + longitude);
                    System.out.println("纬度: " + latitude);
                    // 将经纬度格式化为字符串并返回
                    return String.format("%.6f,%.6f", longitude, latitude);
                }
            }
        }
        return response;
    }

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @ApiOperation(value = "路径规划", notes = "路径规划")
    @ResponseBody
    @RequestMapping(value = "/getRoute2",method = {RequestMethod.GET})
    public void getRoute2() throws IOException {
        String sql = "SELECT " +
                "  t2.id, t2.putgoods_name, t2.address, t2.longitude, t2.latitude, t2.kilometer " +
                "FROM " +
                "  basic_putgoods t1 " +
                "LEFT JOIN basic_address t2 ON t1.id = t2.putgoods_id " +
                "WHERE " +
                "  t1.putgoods_operate_name LIKE '%南京万好供应链管理有限公司天津分公司%' " +
                "  AND IFNULL(t2.kilometer, '') = '' " +
                "  AND t1.unit_type != '供应商' " +
                "  AND t2.longitude != 0";

        try (BufferedWriter writer = new BufferedWriter(new FileWriter("D:\\Office\\Work\\txt\\TJ.txt", true))) {
            // 接口
            List<Map<String, Object>> results = jdbcTemplate.queryForList(sql);

            // 天津起点
            String origin = "117.351155,39.189443";

            for (Map<String, Object> result : results) {

                // 获取终点坐标
                String destination = result.get("longitude") + "," + result.get("latitude");

                StringBuilder stringBuilder = new StringBuilder("https://restapi.amap.com/v3/direction/driving");
                stringBuilder.append("?key=c458de37c0d4d7880ef99c0bfdd58c91");
                stringBuilder.append("&origin=").append(origin);
                stringBuilder.append("&destination=").append(destination);
//                stringBuilder.append("&waypoints=").append(waypoints); // 添加途经点
                stringBuilder.append("&extensions=").append("all");

                try {
                    // 发送GET请求并获取响应
                    String url = stringBuilder.toString();
                    RestTemplate restTemplate = new RestTemplate();
                    String response = restTemplate.getForObject(url, String.class);
                    JSONObject jsonObject = new JSONObject(response);
                    JSONObject route = jsonObject.getJSONObject("route");
                    JSONArray paths = route.getJSONArray("paths");
                    JSONObject path = paths.getJSONObject(0);
                    Double distance = (double) path.getInt("distance");

                    distance = distance / 1000;

                    BasicAddress basicAddress = new BasicAddress();
                    basicAddress.setId((Integer) result.get("id"));
                    basicAddress.setKilometer(distance.toString());
                    basicAddressService.updateById(basicAddress);

                    writer.write("--id:" + (Integer) result.get("id") + "--原kilometer:" + result.get("kilometer") + "--kilometer:" + distance);
                    writer.newLine();
                    writer.flush();  // 确保数据写入
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }


}
